#![allow(dead_code)]
#![allow(unused_variables)]
#![allow(non_camel_case_types)]
#![feature(trait_alias)]

#[macro_use] extern crate cfg_if;
#[macro_use] extern crate bitflags;
#[macro_use] extern crate derive_more;

pub mod bp;
pub mod def;
pub mod regs;
pub mod sym;
pub mod util;
pub mod event;
pub mod range;
pub mod konst;

use def::*;
pub use hackit;

cfg_if! {
    if #[cfg(windows)] {
        pub const PROTO_OS: &str = "windows";
    } else if #[cfg(linux)] {
        pub const PROTO_OS: &str = "linux";
    } else if #[cfg(android)] {
        pub const PROTO_OS: &str = "android";
    } else if #[cfg(macos)] {
        pub const PROTO_OS: &str = "macos";
    } else {
        pub const PROTO_OS: &str = "<unknown>";
    }
}

pub mod error {
    use std::fmt;
    use hackit::*;

    #[derive(Clone, Debug, PartialEq)]
    pub enum UDbgError {
        NotSupport,
        Failure,
        BpExists,
        NotFound,
        TimeOut,
        InvalidAddress,
        InvalidRegister,
        MemoryError,
        HWBPSlotMiss,
        BindFailed,
        SpawnFailed,
        DbgeeIsBusy,
        GetContext(u32),
        SetContext(u32),
        Text(String),
        System(String),
        Code(usize),
    }
    pub type UDbgResult<T>  = Result<T, UDbgError>;
    
    impl UDbgError {
        #[inline]
        pub fn system() -> UDbgError { UDbgError::System(get_last_error_string()) }
    }
    
    impl From<&str> for UDbgError {
        fn from(s: &str) -> Self { UDbgError::Text(s.to_string()) }
    }
    
    impl From<String> for UDbgError {
        fn from(s: String) -> Self { UDbgError::Text(s) }
    }
    
    #[cfg(windows)]
    impl From<WmError> for UDbgError {
        fn from(e: WmError) -> Self { UDbgError::Text(format!("{:?}", e)) }
    }
    
    impl fmt::Display for UDbgError {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            write!(f, "")
        }
    }
    
    impl std::error::Error for UDbgError {}
}